﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Data;
using System.IO;
using System.Xml;
using System.Runtime.CompilerServices;

namespace Bamboo.Utils
{
    public class EntitySerializer
    {
        public Dictionary<string, string> _propDict = new Dictionary<string, string>();
        public Dictionary<string, string> _memoDict = new Dictionary<string, string>();

        public Dictionary<string, DataTable> _tableDict = new Dictionary<string, DataTable>();

        public void SetString(string key, string value)
        {
            _propDict[key] = SingleLineString.FromMultiLine(value);
        }

        public string GetString(string key, string defaultValue)
        {
            string s;
            if (_propDict.TryGetValue(key, out s))
            {
                string s2 = SingleLineString.ToMultiLine(s);
                return s2;
            }
            else
            {
                return defaultValue;
            }
        }

        public void SetMemo(string key, string value)
        {
            _memoDict[key] = value;
        }

        public string GetMemo(string key, string defaultValue)
        {
            string s;
            if (_memoDict.TryGetValue(key, out s))
            {
                string s2 = SingleLineString.ToMultiLine(s);
                return s2;
            }
            else
            {
                return defaultValue;
            }
        }

        public void SetBool(string key, bool value)
        {
            _propDict[key] = value ? "1" : "0";
        }

        public bool GetBool(string key, bool defaultValue) 
        {
            string s;
            if (_propDict.TryGetValue(key, out s))
            {
                if (s == "1") return true;
                else if (s == "0") return false;
                else return defaultValue;
            }
            else
            {
                return defaultValue;
            }
        }

        public void SetInt(string key, int value)
        {
            _propDict[key] = value.ToString();
        }

        public int GetInt(string key, int defaultValue)
        {
            string s;
            if (_propDict.TryGetValue(key, out s))
            {
                int v;
                if (int.TryParse(s, out v)) 
                    return v;
                else 
                    return defaultValue;
            }
            else
            {
                return defaultValue;
            }
        }

        public void SetInt64(string key, long value)
        {
            _propDict[key] = value.ToString();
        }

        public long GetInt64(string key, long defaultValue)
        {
            string s;
            if (_propDict.TryGetValue(key, out s))
            {
                long v;
                if (long.TryParse(s, out v))
                    return v;
                else
                    return defaultValue;
            }
            else
            {
                return defaultValue;
            }
        }

        public void SetDouble(string key, double value)
        {
            _propDict[key] = value.ToString();
        }

        public double GetDouble(string key, double defaultValue)
        {
            string s;
            if (_propDict.TryGetValue(key, out s))
            {
                double v;
                if (double.TryParse(s, out v))
                    return v;
                else
                    return defaultValue;
            }
            else
            {
                return defaultValue;
            }
        }

        public void SetDataTable(string key, DataTable table)
        {
            _tableDict[key] = table;
        } 

        public DataTable GetDataTable(string key)
        {
            DataTable ret;
            if (_tableDict.TryGetValue(key, out ret))
                return ret;
            else
                return null;
        }

        public void SaveXml(string filename, string rootNodeName, bool useGbk)
        {
            var propList = _propDict.ToList();
            propList.Sort((a, b) => a.Key.CompareTo(b.Key));
            var memoList = _memoDict.ToList();
            memoList.Sort((a, b) => a.Key.CompareTo(b.Key));
            var tableList = _tableDict.ToList();
            tableList.Sort((a, b) => a.Key.CompareTo(b.Key));

            var xml = new XmlDocument();
            string encodingName = useGbk ? "gbk" : "utf-8";
            xml.CreateXmlDeclaration("1.0", encodingName, "yes");
            var rootNode = xml.CreateElement(rootNodeName);
            xml.AppendChild(rootNode);
            //写入属性
            foreach (var prop in propList)
            {
                var node = xml.CreateElement("Property");
                rootNode.AppendChild(node);
                node.SetAttribute(prop.Key, prop.Value);
            }
            //写入多行文本
            foreach (var item in memoList)
            {
                var node = xml.CreateElement("Memo");
                rootNode.AppendChild(node);
                node.SetAttribute("name", item.Key);
                node.InnerText = item.Value;
            }
            //写入表格
            foreach (var tablePair in tableList)
            {
                var table = tablePair.Value;
                var node = xml.CreateElement("Table");
                rootNode.AppendChild(node);
                node.SetAttribute("name", tablePair.Key);
                //表头
                foreach (DataColumn column in table.Columns)
                {
                    var cnode = xml.CreateElement("Column");
                    node.AppendChild(cnode);
                    if (!string.IsNullOrWhiteSpace(column.ColumnName))
                    {
                        cnode.SetAttribute("name", column.ColumnName);
                    }
                    if (!string.IsNullOrWhiteSpace(column.Caption))
                    {
                        cnode.SetAttribute("caption", column.Caption);
                    }
                    cnode.SetAttribute("type", column.DataType.FullName);
                }
                //表内容
                foreach (DataRow row in table.Rows)
                {
                    var items = row.ItemArray;
                    var rnode = xml.CreateElement("Row");
                    node.AppendChild(rnode);
                    for (int i = 0; i < table.Columns.Count; ++i)
                    {
                        object obj = items[i];
                        if (obj == null) continue;
                        string name = table.Columns[i].ColumnName;
                        string value = SingleLineString.FromMultiLine(obj.ToString());
                        rnode.SetAttribute(name, value);
                    }
                }
            }
        }

        public void Load(string filename)
        {

        }
    }
}
